package character;

import character.action.CharacterAction;
import com.jme3.bullet.control.GhostControl;
import com.jme3.export.InputCapsule;
import com.jme3.export.JmeExporter;
import com.jme3.export.JmeImporter;
import com.jme3.export.OutputCapsule;
import com.jme3.scene.Node;
import java.io.IOException;
import java.util.ArrayDeque;
import java.util.ArrayList;
import mygame.Inventory;
import mygame.MyCharacterControl;

public abstract class AbstractCharacter extends Node {
    public static final int CHARACTER_ANIM_CHANNEL_WALK = 0;
    public static final String CHARACTER_ANIM_STAND = "stand";
    public static final String CHARACTER_ANIM_WALK = "Walk";
    protected CharacterSettings settings;
    protected CharacterStatus status = new CharacterStatus();
    protected ArrayDeque<CharacterAction> actionQueue = new ArrayDeque<CharacterAction>();

    protected Inventory inventory = new Inventory();

    public AbstractCharacter() {}

    public AbstractCharacter(Node model, CharacterSettings settings, MyCharacterControl characterControl) {
        model.addControl(new GhostControl(characterControl.getCollisionShape()));
	attachChild(model);
	this.settings = settings;
	addControl(characterControl);
	init();
    }

    private void init() {
	//init character status values
	status.setMoveSpeed(settings.getWalkSpeed());
    }

    public Node getModel() {
	return (Node)getChild(0);
    }

    @Override
    public void write(JmeExporter ex) throws IOException {
	super.write(ex);
	OutputCapsule capsule = ex.getCapsule(this);
	capsule.write(settings, "settings", null);
	capsule.write(status, "status", null);
        capsule.writeSavableArrayList(new ArrayList<CharacterAction>(actionQueue), "actionQueue", null);
	capsule.write(inventory, "inventory", null);
    }

    @Override
    @SuppressWarnings("unchecked")
    public void read(JmeImporter im) throws IOException {
	super.read(im);
	InputCapsule capsule = im.getCapsule(this);
	settings = (CharacterSettings)capsule.readSavable("settings", null);
	status = (CharacterStatus)capsule.readSavable("status", null);
        actionQueue = new ArrayDeque<CharacterAction>(capsule.readSavableArrayList("actionQueue", null));
	inventory = (Inventory)capsule.readSavable("inventory", null);
    }

    public CharacterSettings getSettings() {
	return settings;
    }

    public void setSettings(CharacterSettings settings) {
	this.settings = settings;
    }

    public CharacterStatus getStatus() {
	return status;
    }

    public void setStatus(CharacterStatus status) {
	this.status = status;
    }

    public CharacterAction getCurrentAction() {
	return actionQueue.peek();
    }

    public boolean hasAction() {
	return !actionQueue.isEmpty();
    }

    public void completeCurrentAction() {
	actionQueue.pollFirst();
    }

    public void clearActionQueue() {
	actionQueue.clear();
    }

    public void queueActionBack(CharacterAction action) {
	actionQueue.addLast(action);
    }

    public void queueActionFront(CharacterAction action) {
        actionQueue.addFirst(action);
    }

    public Inventory getInventory() {
	return inventory;
    }

    public void setInventory(Inventory inventory) {
	this.inventory = inventory;
    }
}
